﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Actuals.CoreDomain.Business;
using Actuals.CoreDomain;
using Actuals.CoreDomain.Data;
using Actuals.Data;


namespace Actuals.Business
{
    public class BusinessRemainingTime : IBusinessRemainingTime
    {

        IBusinessProject _businessProject;
        IBusinessRelease _businessRelease;
        IBusinessTeamMember _businessTeamMember;
        IBusinessPublicHoliday _businessPublicHoliday;
        IBusinessEmployeeLeave _businessEmployeeLeave;
        IBusinessNoOfDays _businessNoOfDays;
        IBusinessPartTimeDetail _businessPartTimeDetails;
      

        public BusinessRemainingTime()
        {
            _businessProject = new BusinessProject();
            _businessRelease = new BusinessRelease();
            _businessTeamMember = new BusinessTeamMember();
            _businessPublicHoliday = new BusinessPublicHoliday();
            _businessEmployeeLeave = new BusinessEmployeeLeave();
            _businessNoOfDays = new BusinessNoOfDays();
            _businessPartTimeDetails = new BusinessPartTimeDetail();
        }



        #region IBusinessRemainingTime Members

        public double GetReleaseRemainingTime(int projectId, int releaseId)
        {
            IProject project = _businessProject.GetProject(projectId);
            IRelease release = _businessRelease.GetRelease(projectId,releaseId);

            IList<ITeamMember> teamMembers = _businessTeamMember.GetTeamMembers(release.TeamId);
            IList<IPublicHoliday> publicHolidays = _businessPublicHoliday.GetPublicHolidays(release.StartDate, release.EndDate);

            DateTime _startDate=release.StartDate;
            if (release.StartDate < DateTime.Now.Date)
                _startDate = DateTime.Now.Date;

            double _noOfBDays = _businessNoOfDays.CaculateNoOfBusinessDays(_startDate, release.EndDate) - publicHolidays.Count;

            
            double _totalHrsForTeam = 0; ;

            foreach (ITeamMember teamMember in teamMembers)
            {
                if (teamMember.WorkMode=="F")
                    _totalHrsForTeam = _totalHrsForTeam + GetRemainingDaysForEmployee(_startDate, release.EndDate, _noOfBDays) * teamMember.NoOfHoursPerDay ;
                
            }

             foreach (ITeamMember teamMember in teamMembers)
             {
                 if (teamMember.WorkMode == "P")
                 {
                     IList<IPartTimeDetails> partTimeDetailses = _businessPartTimeDetails.GetPartTimeDetails(projectId, releaseId,teamMember.EmployeeId);
                     foreach (IPartTimeDetails partTimeDetails in partTimeDetailses)
                         _totalHrsForTeam = _totalHrsForTeam + partTimeDetails.NoOfHours;
                 }
             }

            return _totalHrsForTeam;
        }


        public bool isHolidayInBetween(DateTime holidayDate, DateTime startDate, DateTime endDate)
        {
            return (holidayDate >= startDate && holidayDate <= endDate);
        }

        public double GetReleaseRemainingTimeAsOfDate(int projectId, int releaseId, DateTime asOfDate)
        {
            IProject project = _businessProject.GetProject(projectId);
            IRelease release = _businessRelease.GetRelease(projectId, releaseId);

            IList<ITeamMember> teamMembers = _businessTeamMember.GetTeamMembers(project.TeamId);
            IList<IPublicHoliday> publicHolidays = _businessPublicHoliday.GetPublicHolidays(release.StartDate, release.EndDate);

            //DateTime _startDate = release.StartDate;
            //if (release.StartDate < DateTime.Now.Date)
            //    _startDate = DateTime.Now.Date;

            double _totalHrsForTeam = 0; ;

            if (asOfDate > release.EndDate)
            {
                _totalHrsForTeam = 0;
            }

            else
            {
                double _noOfBDays;
                _noOfBDays = _businessNoOfDays.CaculateNoOfBusinessDays(asOfDate, release.EndDate);

                foreach(IPublicHoliday publicHoliday in publicHolidays)
                {
                    if (isHolidayInBetween(publicHoliday.HolidayDate, asOfDate, release.EndDate))
                    {

                        _noOfBDays = _noOfBDays - 1;
                    }
                }




                foreach (ITeamMember teamMember in teamMembers)
                {
                    if (teamMember.WorkMode == "F")
                        _totalHrsForTeam = _totalHrsForTeam +
                                           GetRemainingDaysForEmployee(asOfDate, release.EndDate, _noOfBDays)*
                                           teamMember.NoOfHoursPerDay;

                }

                foreach (ITeamMember teamMember in teamMembers)
                {
                    if (teamMember.WorkMode == "P")
                    {
                        IList<IPartTimeDetails> partTimeDetailses =
                            _businessPartTimeDetails.GetPartTimeDetails(projectId, releaseId, teamMember.EmployeeId);
                        foreach (IPartTimeDetails partTimeDetails in partTimeDetailses)
                        {
                            if (isHolidayInBetween(partTimeDetails.WorkDate, asOfDate, release.EndDate))
                                _totalHrsForTeam = _totalHrsForTeam + partTimeDetails.NoOfHours;
                        }
                    }
                }
            }

            return _totalHrsForTeam;
        }

        public double GetRemainingDaysForEmployee(DateTime _startDate, DateTime _endDate, double _totalBDays)
        {
            IList<IEmployeeLeave> employeeLeaves = _businessEmployeeLeave.GetEmployeeLeaves(_startDate, _endDate);

                foreach (IEmployeeLeave employeeLeave in employeeLeaves)
                {
                    if (employeeLeave.AM)
                        _totalBDays = _totalBDays - 0.5;
                    if (employeeLeave.PM)
                        _totalBDays = _totalBDays - 0.5;
                }

                return _totalBDays;
        }

        #endregion
    }
}
